﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;
using System.IO;

namespace Assets.Scripts.LDS
{

    // Translate: Finished
    // Debug: 


    class TextSemGraphManager
    {

        public List<TextSemGraph> m_textSemGraphs = new List<TextSemGraph>();

        int m_activeGraphId = 0;
        int m_textGraphNum = 0;
        int m_sentence_count;

        public void LoadSELFromOutput(string filename, RelationModelManager relManager)
        {
            m_textSemGraphs.Clear();
            
            TextDialog.textDebug("TextSemGraphManager:Loading SEL parsing result file ... ");

            List<SelSentence> sentences = ReadSentences(filename);
            foreach(SelSentence newSentence in sentences)
            {
                TextSemGraph newTextSemGraph = new TextSemGraph(newSentence, relManager, newSentence.isCommand);
                m_textSemGraphs.Add(newTextSemGraph);
                m_textGraphNum++;
            }
        }

        static public List<SelSentence> ReadSentences(string file_pth)
        {
            List<SelSentence> sentences = new List<SelSentence>();

            using (StreamReader F = new StreamReader(file_pth))
            {
                string SEL_version = F.ReadLine();

                string currLine = F.ReadLine();
                int sentence_count = Util.StringToIntegerList(currLine, "sentence-count:")[0];

                currLine = F.ReadLine();
                for (int si = 0; si < sentence_count; si++)
                {
                    SelSentence newSentence = new SelSentence();

                    // read sentence id and string	
                    if (currLine.IndexOf("sentence-") > -1)
                    {
                        newSentence.id = Util.StringToIntegerList(currLine, "sentence-")[0];
                        newSentence.textString = F.ReadLine();
                    }
                    else
                    {
                        Debug.LogError("ReadSentences Error: currline wrong");
                        continue;
                    }

                    // read entity count
                    currLine = F.ReadLine();
                    if (currLine.IndexOf("entity-count") > -1)
                    {
                        newSentence.entityCount = Util.StringToIntegerList(currLine, "entity-count:")[0];
                    }

                    currLine = F.ReadLine();// now currline is the next sentence
                    for (int ei = 0; ei < newSentence.entityCount; ei++)
                    {
                        if (currLine.IndexOf("entity-") > -1)
                        {
                            SelEntity newEntity = new SelEntity();
                            newEntity.id = Util.StringToIntegerList(currLine, "entity-")[0];

                            currLine = F.ReadLine();// from now currline is next sentence not last sentence
                            while (currLine.IndexOf("sentence-") == -1 &&
                                currLine.IndexOf("entity-") == -1 &&
                                currLine.IndexOf("***") == -1 &&
                                currLine.IndexOf("command") == -1)
                            {
                                if (currLine.IndexOf("id:") > -1)
                                {
                                    List<string> parts = Util.PartitionString(currLine, ":");
                                    newEntity.nameString = parts[1];
                                }

                                if (currLine.IndexOf("plural") > -1)
                                {
                                    newEntity.isPlural = Convert.ToBoolean(Util.StringToIntegerList(currLine, "plural:")[0]);
                                }

                                if (currLine.Substring(0, 5) == "count")
                                {
                                    List<string> parts = Util.PartitionString(currLine, ":");
                                    newEntity.instanceCountString = parts[1];
                                }

                                if (currLine.IndexOf("determiners") > -1)
                                {
                                    List<string> parts = Util.PartitionString(currLine, ":");
                                    if (parts.ToArray().Length > 1)
                                    {
                                        newEntity.m_determiner = parts[1];
                                        newEntity.m_determiner.Replace(",", "");
                                    }
                                }

                                if (currLine.IndexOf("attributes") > -1)
                                {
                                    newEntity.attributeCount = Util.StringToIntegerList(currLine, "attributes:")[0];

                                    for (int ai = 0; ai < newEntity.attributeCount; ai++)
                                    {
                                        SelAttribute newAttribute;
                                        newAttribute.id = ai;

                                        currLine = F.ReadLine();
                                        newAttribute.nameString = currLine;
                                        newEntity.m_attributes.Add(newAttribute);
                                    }
                                }

                                if (currLine.IndexOf("relationship-count") > -1)
                                {
                                    newEntity.relationshipCount = Util.StringToIntegerList(currLine, "relationship-count:")[0];

                                    for (int ri = 0; ri < newEntity.relationshipCount; ri++)
                                    {
                                        currLine = F.ReadLine();
                                        SelRelationship newRelationship;
                                        newRelationship.id = ri;
                                        List<string> parts = Util.PartitionString(currLine, ":");
                                        newRelationship.nameString = parts[0];
                                        newRelationship.entityString = parts[1];

                                        newEntity.m_relationships.Add(newRelationship);
                                    }
                                }

                                currLine = F.ReadLine();
                            }

                            newSentence.m_entities.Add(newEntity);
                        }
                    }   // end of loop for entity

                    

                    // parse for command
                    if (currLine.IndexOf("command-count") > -1)
                    {
                        int commandCount = Util.StringToIntegerList(currLine, "command-count:")[0];
                        newSentence.commandCount = commandCount;

                        currLine = F.ReadLine(); // currline is the next sentence
                        for (int ci = 0; ci < commandCount; ci++)
                        {
                            SelCommand newCommand = new SelCommand();
                            newCommand.id = Util.StringToIntegerList(currLine, "command-")[0];

                            currLine = F.ReadLine();
                            List<string> parts = Util.PartitionString(currLine, ":");
                            newCommand.verbString = parts[1];

                            currLine = F.ReadLine();
                            newCommand.isApplied = Convert.ToBoolean(Util.StringToIntegerList(currLine, "applied:")[0]);

                            currLine = F.ReadLine();
                            newCommand.attributeCount = Util.StringToIntegerList(currLine, "attribute-count:")[0];

                            for (int cai = 0; cai < newCommand.attributeCount; cai++)
                            {
                                currLine = F.ReadLine();
                                newCommand.attributeStrings.Add(currLine);
                            }

                            currLine = F.ReadLine();
                            newCommand.targetCount = Util.StringToIntegerList(currLine, "target-count:")[0];

                            for (int ti = 0; ti < newCommand.targetCount; ti++)
                            {
                                currLine = F.ReadLine();
                                newCommand.targetStrings.Add(currLine);
                            }

                            // only consider the command that is not applied
                            if (newCommand.isApplied == false)
                            {
                                newSentence.m_commands.Add(newCommand);
                                newSentence.isCommand = true;
                            }

                            currLine = F.ReadLine();
                        }
                    }

                    sentences.Add(newSentence);
                    TextDialog.textDebug("Sentence has read:"+newSentence.textString);
                }
            }

            return sentences;
        }

        public void updateActiveGraphId()
        {
            m_activeGraphId++;

            if (m_activeGraphId == m_textSemGraphs.Count)
            {
                m_activeGraphId = m_textSemGraphs.Count - 1;
            }
        }


        public TextSemGraph getActiveGraph() { return m_textSemGraphs[m_activeGraphId]; }

    }
}

